package br.com.trabalho.banco;

import br.com.trabalho.entidades.Comentario;
import br.com.trabalho.entidades.Ingrediente;
import br.com.trabalho.entidades.Receita;
import br.com.trabalho.entidades.Usuario;
import br.com.trabalho.entidades.ReceitaAvaliada;
import br.com.trabalho.util.HibernateUtil;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class Transacoes {
    
    public static void inserirUsuario(Usuario u) throws usuarioJaExisteException{
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        Query q = session.createQuery("from Usuario u where u.email=:email");
        q.setParameter("email", u.getEmail());
        
        if(q.list().size()>0){
            tx.commit();
            session.close();
            throw new usuarioJaExisteException();
        }
        
        session.save(u);
        tx.commit();        
        session.close();
    }
    
    public static void atualizarUsuario(Usuario u) throws usuarioJaExisteException{
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        Query q = session.createQuery("from Usuario u where u.email=:email AND u.id<>:id");
        q.setParameter("email", u.getEmail());
        q.setParameter("id", u.getId());
        
        if(q.list().size()>0){
            tx.commit();
            session.close();
            throw new usuarioJaExisteException();
        }
        
        session.update(u);
        tx.commit(); 
        session.close();
    }
    
    public static void removerUsuario(Usuario u){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        session.delete(u);
        tx.commit(); 
        session.close();
    }
    
    public static Usuario getUsuarioById(int id){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        Query q = session.createQuery("from Usuario u where u.id=:id");
        q.setParameter("id", id);
        
        Usuario u =(Usuario) q.list().get(0);
        tx.commit(); 
        session.close();
        
        return u;
    }
    
    public static List<Usuario> getUsuarios(){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        Query q = session.createQuery("from Usuario u");
        
        List<Usuario> usuarios =(List<Usuario>) q.list();
        tx.commit(); 
        session.close();
        
        return usuarios;
    }
    
    public static Usuario realizarLogin(String email,String senha) throws UsuarioOuSenhaInvalidoException{
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        Query q = session.createQuery("from Usuario u where u.email=:email AND u.senha=:senha");
        q.setParameter("email", email);
        q.setParameter("senha", senha);
        
        Usuario u = null;
        
        try{
            u =(Usuario) q.list().get(0);
        }catch(Exception e){
            tx.commit();
            session.close();
            throw new UsuarioOuSenhaInvalidoException();
        }
        tx.commit(); 
        session.close();
        
        return u;    
    }
    
    /********************************/
    
    public static void inserirReceita(Receita r){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        session.save(r);
        tx.commit();
        session.close();
    }
    
    public static void atualizarReceita(Receita r){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        session.update(r);
        tx.commit(); 
        session.close();
    }
    
    public static void removerReceita(Receita r){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        session.delete(r);
        tx.commit(); 
        session.close();
    }
    
    public static Receita getReceitaById(int id){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        Query q = session.createQuery("from Receita r where r.id=:id");
        q.setParameter("id", id);
        
        Receita r =(Receita) q.list().get(0);
        tx.commit(); 
        session.close();
        
        return r;
    }
    
    public static List<Receita> getReceitas(){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        Query q = session.createQuery("from Receita r");
        
        List<Receita> r =(List<Receita>) q.list();
        tx.commit(); 
        session.close();
        
        return r;
    }
    
    public static List<Receita> buscaReceita(String chave){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        Query q = session.createQuery("from Receita r where LOWER(r.nome) LIKE LOWER(:chave)");
        q.setParameter("chave","%"+chave+"%");
        
        List<Receita> r =(List<Receita>) q.list();
        tx.commit(); 
        session.close();
        
        return r;
    }
    
    public static List<Receita> buscaReceitaCategoria(String chave){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        Query q = session.createQuery("from Receita r where LOWER(r.categoria) LIKE LOWER(:chave)");
        q.setParameter("chave","%"+chave+"%");
        
        List<Receita> r =(List<Receita>) q.list();
        tx.commit(); 
        session.close();
        
        return r;
    }
    
    /********************************/
    
    public static void inserirAvaliacaoReceita(ReceitaAvaliada r){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        session.save(r);
        tx.commit(); 
        session.close();
    }
    
    public static void atualizarAvaliacaoReceita(ReceitaAvaliada r){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        session.update(r);
        tx.commit(); 
        session.close();}
    
    public static long getMediaAvaliacaoReceita(Receita r){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        Query q = session.createQuery("from ReceitaAvaliada r where r.receita=:receita");
        q.setParameter("receita", r);
        List<ReceitaAvaliada> receitas = (List<ReceitaAvaliada>) q.list();
        
        int soma=0,count=0;
        for(ReceitaAvaliada receita:receitas){
            soma=soma+receita.getNota();
            count++;
        }        
        tx.commit(); 
        session.close();
        return soma/count;
    }
    
    public static ReceitaAvaliada getNotaReceitaByUsuario(Receita r, Usuario u){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        Query q = session.createQuery("from ReceitaAvaliada r where r.usuario=:usuario AND r.receita=:receita");
        q.setParameter("receita", r);
        q.setParameter("usuario", u);
        ReceitaAvaliada receita = null;
        
        try{
            receita =(ReceitaAvaliada) q.list().get(0);
        }catch(Exception e){
            ReceitaAvaliada ra = new ReceitaAvaliada();
            ra.setReceita(r);
            ra.setUsuario(u);
            ra.setNota(0);
            Transacoes.inserirAvaliacaoReceita(ra);
            return ra;
        }
        tx.commit(); 
        session.close();
        
        return receita;
    }
    
    /*************************/
    
    public static void inserirComentario(Comentario c){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        session.save(c);
        tx.commit();
        session.close();
    }
    
    /*************************/
    
    public static void inserirIngrediente(Ingrediente i){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        session.save(i);
        tx.commit();
        session.close();
    }    
    
    public static void removerIngrediente(Ingrediente i){
        Session session =  HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        session.delete(i);
        tx.commit();
        session.close();
    }

    public static class UsuarioOuSenhaInvalidoException extends Exception {
        private static final long serialVersionUID = -1112796931277761454L;

        public UsuarioOuSenhaInvalidoException() {
        }
    }

    public static class usuarioJaExisteException extends Exception {

        public usuarioJaExisteException() {
        }
    }
}
